let activeEffect
let effectStack = []
/**
 * 关于依赖
 * 从数据的角度,依赖是指依赖该属性的[副作用函数]
 */
function cleanup (effectFn) {
  for (let i = 0; i < effectFn.deps.length; i++) {
    effectFn.deps[i].delete(effectFn)
  }
  effectFn.deps.length = 0
}
function effect (fn,options={}) {
  const effectFn = () => {
    console.log('effectFn executed')
    cleanup(effectFn)
    activeEffect = effectFn
    effectStack.push(effectFn)
    fn()
    effectStack.pop()
    activeEffect = effectStack[effectStack.length - 1]
  }
  effectFn.options = options
  effectFn.deps = []
  effectFn()
}

/**
 * 副作用函数中被读取的数据必须被代理
 */
//全局响应式存放的中心
let bucket = new WeakMap()
function track (target, key) {
  if (!activeEffect) return target[key]
  let depsMap = bucket.get(target)
  if (!depsMap) {
    bucket.set(target, (depsMap = new Map()))
  }
  let deps = depsMap.get(key)
  if (!deps) {
    depsMap.set(key, (deps = new Set()))
  }
  deps.add(activeEffect)
  activeEffect.deps.push(deps)
}

function trigger (target, key) {
  let depsMap = bucket.get(target)
  if (!depsMap) {
    return
  }
  const effects = depsMap.get(key)
  let effectsToRun = new Set()
  effects &&
    effects.forEach(effectFn => {
      if (effectFn != activeEffect) {
        effectsToRun.add(effectFn)
      }
    })
  effectsToRun.forEach(effectFn => {
     if(effectFn.options.scheduler){
        effectFn.options.scheduler(effectFn)
     }else{
        effectFn()
     }
  })
}
function proxyData (data) {
  return new Proxy(data, {
    get (target, key) {
      track(target, key)
      return target[key]
    },
    set (target, key, newVal) {
      target[key] = newVal
      trigger(target, key)
    }
  })
}


export {
    trigger,
    track,
    effect
}
